﻿Public Class MaterialArgVm
    Inherits ArgumentBaseVm
    Public Overrides Sub Init(token As TokenBaseVm, obj As RawObjectVm, arg As ArgumentDefinition, value As String)
        MyBase.Init(token, obj, arg, value)
        Setup()
    End Sub

    Public ReadOnly Property BuiltInMaterials As IEnumerable(Of String)
        Get
            Return MaterialArgHandler.BuiltInMaterials
        End Get
    End Property

#Region "Visibility"
    Private mLine1Visibility As Visibility = Visibility.Visible
    Public Property Line1Visibility As Visibility
        Get
            Return mLine1Visibility
        End Get
        Set(value As Visibility)
            If mLine1Visibility <> value Then
                mLine1Visibility = value
                RaisePropertyChanged("Line1Visibility")
            End If
        End Set
    End Property

    Private mLine2Visibility As Visibility = Visibility.Hidden
    Public Property Line2Visibility As Visibility
        Get
            Return mLine2Visibility
        End Get
        Set(value As Visibility)
            If mLine2Visibility <> value Then
                mLine2Visibility = value
                RaisePropertyChanged("Line2Visibility")
            End If
        End Set
    End Property

    Private mLine3Visibility As Visibility = Visibility.Hidden
    Public Property Line3Visibility As Visibility
        Get
            Return mLine3Visibility
        End Get
        Set(value As Visibility)
            If mLine3Visibility <> value Then
                mLine3Visibility = value
                RaisePropertyChanged("Line3Visibility")
            End If
        End Set
    End Property
#End Region

#Region "Text"
    Private mLine1LabelText As String = "Type:"
    Public Property Line1LabelText As String
        Get
            Return mLine1LabelText
        End Get
        Set(value As String)
            If mLine1LabelText <> value Then
                mLine1LabelText = value
                RaisePropertyChanged("Line1LabelText")
            End If
        End Set
    End Property

    Private mLine2LabelText As String = "Sub Type:"
    Public Property Line2LabelText As String
        Get
            Return mLine2LabelText
        End Get
        Set(value As String)
            If mLine2LabelText <> value Then
                mLine2LabelText = value
                RaisePropertyChanged("Line2LabelText")
            End If
        End Set
    End Property

    Private mLine3LabelText As String = "Object ID:"
    Public Property Line3LabelText As String
        Get
            Return mLine3LabelText
        End Get
        Set(value As String)
            If mLine3LabelText <> value Then
                mLine3LabelText = value
                RaisePropertyChanged("Line3LabelText")
            End If
        End Set
    End Property
#End Region

#Region "DataSource"
    Private mLine1DataSource As List(Of String)
    Public Property Line1DataSource As List(Of String)
        Get
            Return mLine1DataSource
        End Get
        Set(value As List(Of String))
            If mLine1DataSource IsNot value Then
                mLine1DataSource = value
                RaisePropertyChanged("Line1DataSource")
            End If
        End Set
    End Property

    Private mLine2DataSource As List(Of String)
    Public Property Line2DataSource As List(Of String)
        Get
            Return mLine2DataSource
        End Get
        Set(value As List(Of String))
            If mLine2DataSource IsNot value Then
                mLine2DataSource = value
                RaisePropertyChanged("Line2DataSource")
            End If
        End Set
    End Property

    Private mLine3DataSource As List(Of String)
    Public Property Line3DataSource As List(Of String)
        Get
            Return mLine3DataSource
        End Get
        Set(value As List(Of String))
            If mLine3DataSource IsNot value Then
                mLine3DataSource = value
                RaisePropertyChanged("Line3DataSource")
            End If
        End Set
    End Property
#End Region

#Region "SelectedItem"
    Private mLine1SelectedItem As String
    Public Property Line1SelectedItem As String
        Get
            Return mLine1SelectedItem
        End Get
        Set(value As String)
            If mLine1SelectedItem IsNot value Then
                mLine1SelectedItem = value
                RaisePropertyChanged("Line1SelectedItem")
                Line1Changed()
            End If
        End Set
    End Property

    Private mLine2SelectedItem As String
    Public Property Line2SelectedItem As String
        Get
            Return mLine2SelectedItem
        End Get
        Set(value As String)
            If mLine2SelectedItem IsNot value Then
                mLine2SelectedItem = value
                RaisePropertyChanged("Line2SelectedItem")
                Line2Changed()
            End If
        End Set
    End Property

    Private mLine3SelectedItem As String
    Public Property Line3SelectedItem As String
        Get
            Return mLine3SelectedItem
        End Get
        Set(value As String)
            If mLine3SelectedItem IsNot value Then
                mLine3SelectedItem = value
                RaisePropertyChanged("Line3SelectedItem")
            End If
        End Set
    End Property
#End Region

#Region "Enabled"
    Private mLine1Enabled As Boolean = True
    Public Property Line1Enabled As Boolean
        Get
            Return mLine1Enabled
        End Get
        Set(value As Boolean)
            If mLine1Enabled <> value Then
                mLine1Enabled = value
                RaisePropertyChanged("Line1Enabled")
                Line1Changed()
            End If
        End Set
    End Property

    Private mLine2Enabled As Boolean = True
    Public Property Line2Enabled As Boolean
        Get
            Return mLine2Enabled
        End Get
        Set(value As Boolean)
            If mLine2Enabled <> value Then
                mLine2Enabled = value
                RaisePropertyChanged("Line2Enabled")
            End If
        End Set
    End Property

    Private mLine3Enabled As Boolean = True
    Public Property Line3Enabled As Boolean
        Get
            Return mLine3Enabled
        End Get
        Set(value As Boolean)
            If mLine3Enabled <> value Then
                mLine3Enabled = value
                RaisePropertyChanged("Line3Enabled")
            End If
        End Set
    End Property
#End Region

    Private mOutput As String
    Public ReadOnly Property output As String
        Get
            Return mOutput
        End Get
    End Property

    Private mIsInCreatureMode As Boolean

    Public Sub Setup()
        Dim token As Token = MyBase.Token.Token

        'figure out if the previous argument is an item type that uses a creature material
        mIsInCreatureMode = False
        Dim index As Integer = token.Arguments.IndexOf(Value)
        If index > 0 Then
            Dim usage As TokenUsage = TokenDictionary.Instance.GetUsage(token.Name, Me.RawObject.ObjectType, Me.RawObject.ObjectSubType)
            If usage IsNot Nothing AndAlso usage.Arguments(index - 1).Type = ArgType.Item Then
                Dim itemParts() As String = token.Arguments(index - 1).Split(":"c)
                If itemParts.Count > 0 AndAlso TokenLib.MaterialArgHandler.CreatureItems.Contains(itemParts(0)) Then
                    mIsInCreatureMode = True
                End If
            End If
        End If

        'mMaterialArg = Value
        'mOutput = materialArg

        If Not mIsInCreatureMode Then

            Line1LabelText = "Type:"

            If Value IsNot Nothing Then
                Dim materialTypes As New List(Of String)

                materialTypes.AddRange(MaterialArgHandler.BuiltInMaterials)
                materialTypes.AddRange({"INORGANIC", "METAL", "STONE"})
                materialTypes.Sort()

                materialTypes.Add("CREATURE_MAT")
                If RawObject.ObjectSubType = ObjectSubType.CREATURE Then
                    materialTypes.Add("LOCAL_CREATURE_MAT")
                End If
                materialTypes.Add("PLANT_MAT")
                If RawObject.ObjectSubType = ObjectSubType.PLANT Then
                    materialTypes.Add("LOCAL_PLANT_MAT")
                End If
                If RawObject.ObjectSubType = ObjectSubType.REACTION AndAlso token.Name = "PRODUCT" Then
                    materialTypes.Add("GET_MATERIAL_FROM_REAGENT")
                End If
                If RawObject.ObjectType = ObjectType.REACTION And token.Name = "REAGENT" Then
                    materialTypes.Add("NONE")
                End If

                Line1DataSource = materialTypes
                Line1Visibility = Visibility.Visible

                Dim parts() As String = Value.Split(":"c)
                If parts.Count > 0 Then
                    Dim type As String = parts(0)
                    If materialTypes.Contains(type) Then
                        Line1SelectedItem = type
                    Else
                        Line1SelectedItem = Line1DataSource(0)
                    End If

                    If MaterialArgHandler.BuiltInMaterials.Contains(type) Then
                        Line2SelectedItem = getArg(1)
                    Else
                        Select Case type
                            Case "INORGANIC", "STONE", "METAL", "NONE"
                                Line2SelectedItem = getArg(1)
                                Line2LabelText = "Sub Type:"

                                Line2Visibility = Visibility.Visible
                                Line3Visibility = Visibility.Hidden

                            Case "CREATURE_MAT", "PLANT_MAT"
                                Line2SelectedItem = getArg(1)
                                Line3SelectedItem = getArg(2)

                                Line2LabelText = "Creature ID:"
                                Line3LabelText = "Material:"

                                Line2Visibility = Visibility.Visible
                                Line3Visibility = Visibility.Visible

                            Case "LOCAL_CREATURE_MAT", "LOCAL_PLANT_MAT"
                                Line2SelectedItem = getArg(1)

                                Line2LabelText = "Material ID:"

                                Line2Visibility = Visibility.Visible
                                Line3Visibility = Visibility.Hidden

                            Case "GET_MATERIAL_FROM_REAGENT"
                                Line2SelectedItem = getArg(1)
                                Line3SelectedItem = getArg(2)

                                Line2LabelText = "Reagent::"
                                Line3LabelText = "Product:"

                                Line2Visibility = Visibility.Visible
                                Line3Visibility = Visibility.Visible
                        End Select
                    End If
                End If
            End If
        Else
            Line1LabelText = "Creature:"
            Line2LabelText = "Caste:"
            Line2Visibility = Visibility.Visible
            Line3Visibility = Visibility.Hidden

            If RawObject.ObjectType = ObjectType.REACTION AndAlso RawObject.ObjectSubType = ObjectSubType.REACTION Then
                For Each creature As RawObject In RawObject.Library.GetObjectsByType(ObjectType.CREATURE, ObjectSubType.CREATURE).OrderBy(Function(x As RawObject) x.ObjectId)
                    Line1DataSource.Add(creature.ObjectId)
                Next
            End If
            Line1SelectedItem = getArg(0)
        End If
    End Sub

    Private Sub Line1Changed()
        Dim type As String = Line1SelectedItem
        Dim line2Items As New List(Of String)
        Dim line3Items As New List(Of String)

        Line2Enabled = True
        Line3Enabled = True

        If Not mIsInCreatureMode Then
            If MaterialArgHandler.BuiltInMaterials.Contains(type) OrElse type = "NONE" Then
                Line2Visibility = Visibility.Visible
                Line3Visibility = Visibility.Hidden

                Line2LabelText = "Sub Type:"

                If type = "COAL" Then
                    line2Items.Add("COKE")
                    line2Items.Add("CHARCOAL")
                    Line2DataSource = line2Items
                    Line2SelectedItem = getArg(1)
                Else
                    line2Items.Add("NONE")
                    Line2DataSource = line2Items
                    Line2SelectedItem = "NONE"
                    Line2Enabled = False
                End If
            Else
                Select Case type
                    Case "INORGANIC", "STONE", "METAL"
                        Line2Visibility = Visibility.Visible
                        Line3Visibility = Visibility.Hidden

                        Line2LabelText = "Creature ID:"
                        Line3LabelText = "Material:"

                        Dim source As IEnumerable(Of RawObject) = RawObject.Library.GetObjectsByType(ObjectType.INORGANIC, ObjectSubType.INORGANIC)
                        Dim filteredSource As IEnumerable(Of RawObject) = source
                        Select Case type
                            'Case "INORGANIC"
                            '    filteredSource = source
                            Case "STONE"
                                filteredSource = source.Where(Function(x As RawObject) x.HasToken("IS_STONE"))
                            Case "METAL"
                                filteredSource = source.Where(Function(x As RawObject) x.HasToken("IS_METAL"))
                        End Select
                        Dim data As New List(Of String)
                        For Each obj As RawObject In filteredSource
                            data.Add(obj.ObjectId)
                        Next
                        data.Sort()
                        data.Add("USE_LAVA_STONE")
                        line2Items.AddRange(data)
                        Line2DataSource = line2Items
                        Line2SelectedItem = getArg(1)
                    Case "CREATURE_MAT", "PLANT_MAT"
                        Line2Visibility = Visibility.Visible
                        Line3Visibility = Visibility.Visible

                        Line3LabelText = "Material:"

                        Dim data As New List(Of String)
                        Dim source As IEnumerable(Of RawObject)
                        If type = "CREATURE_MAT" Then
                            Line2LabelText = "Creature ID:"
                            source = RawObject.Library.GetObjectsByType(ObjectType.CREATURE, ObjectSubType.CREATURE)
                        Else
                            Line2LabelText = "Plant ID:"
                            source = RawObject.Library.GetObjectsByType(ObjectType.PLANT, ObjectSubType.PLANT)
                        End If
                        For Each obj As RawObject In source
                            data.Add(obj.ObjectId)
                        Next
                        data.Sort()
                        line2Items.AddRange(data)
                        Line2DataSource = line2Items
                        If line2Items.Contains(getArg(1)) Then
                            Line2SelectedItem = getArg(1)
                        Else
                            Line2SelectedItem = line2Items(0)
                        End If
                        'cboBox2_SelectedIndexChanged(cboBox2, EventArgs.Empty)

                    Case "LOCAL_CREATURE_MAT", "LOCAL_PLANT_MAT"
                        Line2Visibility = Visibility.Visible
                        Line3Visibility = Visibility.Hidden

                        Line2LabelText = "Material:"

                        Dim data As New List(Of String)
                        data.AddRange(RawObject.GetMaterials)
                        data.Sort()
                        line2Items.AddRange(data)
                        Line2DataSource = line2Items
                        Line2SelectedItem = getArg(1)
                    Case "GET_MATERIAL_FROM_REAGENT"
                        Line2Visibility = Visibility.Visible
                        Line3Visibility = Visibility.Visible

                        Line2LabelText = "Reagent:"
                        Line3LabelText = "Product:"

                        'populate reagents
                        For Each token As String In RawObject.GetTokenArguments("REAGENT", True)
                            Dim parts() As String = token.Split(":"c)

                            line2Items.Add(parts(0))
                        Next

                        'populate products
                        For Each token As String In RawObject.GetTokenArguments("HAS_MATERIAL_REACTION_PRODUCT", True)
                            Dim parts() As String = token.Split(":"c)

                            line3Items.Add(parts(0))
                        Next
                        Line2DataSource = line2Items
                        Line3DataSource = line3Items
                End Select
            End If
        Else
            Dim creature As RawObject = RawObject.Library.GetObjectById(Line1SelectedItem)
            If creature IsNot Nothing Then
                For Each casteArgs As String In creature.GetTokenArguments("CASTE", True)
                    Dim casteParts() As String = casteArgs.Split(":"c)
                    If casteParts.Count >= 1 Then
                        line2Items.Add(casteParts(0))
                    End If
                Next
            Else
                line2Items.Add("NONE")
            End If
            Line2DataSource = line2Items
            Line2SelectedItem = getArg(1, "NONE")
        End If
    End Sub

    Private Sub Line2Changed()
        Select Case Line1SelectedItem
            Case "CREATURE_MAT", "PLANT_MAT"
                Dim obj As RawObject = RawObject.Library.GetObjectById(Line2SelectedItem)
                If obj IsNot Nothing Then

                    Dim data As New List(Of String)(obj.GetMaterials)
                    data.Sort()

                    Line3DataSource = data

                    If data.Contains(getArg(2)) Then
                        Line3SelectedItem = getArg(2)
                    Else
                        Line3SelectedItem = data(0)
                    End If
                Else
                    Line3SelectedItem = Nothing
                End If
        End Select
    End Sub

    Private Function getArg(index As Integer) As String
        Return getArg(index, "NONE")
    End Function

    Private Function getArg(index As Integer, [default] As String) As String
        Dim arglist() As String = Value.Split(":"c)
        If index < arglist.Count Then
            Return arglist(index)
        Else
            Return [default]
        End If
    End Function

End Class
